#ifndef __BHTTP_BCLIENT_H__
#define __BHTTP_BCLIENT_H__
#pragma once

#include "brequest.h"
#include "bresponse.h"
#include "bthreadpool.h"

namespace bhttp
{
using brequest_ptr = std::shared_ptr<brequest>;
using bresponse_ptr = std::shared_ptr<bresponse>;
using bcallback = std::function<void(const std::shared_ptr<brequest>&, const std::shared_ptr<bresponse>&)>;

class bclient
{
public:
	static bclient* instance();

	void timeout_connect(int value);
	int timeout_connect() const;

	void timeout_read(int value);
	int timeout_read() const;

	void ssl_verfication(const std::string& ca);
	void ssl_verfication(std::string&& ca);
	const std::string& ssl_verfication() const;

	void send(const std::shared_ptr<brequest>& req, bcallback cb);
	void send_immediate(const std::shared_ptr<brequest>& req, bcallback cb);

private:
	explicit bclient();
	~bclient();
	bclient(const bclient&) = delete;
	bclient& operator=(const bclient&) = delete;
	bclient(const bclient&&) = delete;
	bclient& operator=(const bclient&&) = delete;

	void process(const std::shared_ptr<brequest>& req, std::shared_ptr<bresponse>& rep, bcallback cb);
	void get(const std::shared_ptr<brequest>& req, std::shared_ptr<bresponse>& rep);
	void post(const std::shared_ptr<brequest>& req, std::shared_ptr<bresponse>& rep);
	void del(const std::shared_ptr<brequest>& req, std::shared_ptr<bresponse>& rep);
    void put(const std::shared_ptr<brequest>& req, std::shared_ptr<bresponse>& rep);
    void patch(const std::shared_ptr<brequest>& req, std::shared_ptr<bresponse>& rep);
private:
	static const int k_thd_cnt = 2;
	static const int k_error_buf_size = 256;
	
	mutable std::mutex ssl_ca_file_mtx_;
	std::string ssl_ca_fname_;

	int timeout_connect_{ 30 };
	int timeout_read_{ 60 };

	std::shared_ptr<bthreadpool> thpool_;
};

}

#endif //__BHTTP_CLIENT_H__
